package com.my.core.util.file;

import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

/**
 * 文件信息工具类：获取文件格式、大小等属性，以及文件删除功能
 */
public class FileInfoUtils {

    /**
     * 封装文件信息的内部类
     */
    public static class FileInfo {
        private String fileFormat;      // 文件格式（如 mp4、jpg）
        private String fileSize;        // 格式化后的文件大小（如 2.34 MB）
        private long fileSizeBytes;     // 原始字节数

        // 构造方法
        public FileInfo(String fileFormat, String fileSize, long fileSizeBytes) {
            this.fileFormat = fileFormat;
            this.fileSize = fileSize;
            this.fileSizeBytes = fileSizeBytes;
        }

        // Getter
        public String getFileFormat() { return fileFormat; }
        public String getFileSize() { return fileSize; }
        public long getFileSizeBytes() { return fileSizeBytes; }
    }

    /**
     * 批量删除结果封装类
     */
    public static class BatchDeleteResult {
        private int totalCount;         // 总文件数
        private int successCount;       // 成功删除数
        private int failCount;          // 删除失败数
        private String failDetails;     // 失败详情

        public BatchDeleteResult(int totalCount, int successCount, int failCount, String failDetails) {
            this.totalCount = totalCount;
            this.successCount = successCount;
            this.failCount = failCount;
            this.failDetails = failDetails;
        }

        // Getter
        public int getTotalCount() { return totalCount; }
        public int getSuccessCount() { return successCount; }
        public int getFailCount() { return failCount; }
        public String getFailDetails() { return failDetails; }
    }

    /**
     * 根据文件根路径和相对路径获取文件信息
     * @param uploadRootPath 服务器文件上传根路径（如 D:/jeecg/upload）
     * @param relativePath 文件相对路径（如 upload/202410/abc.mp4）
     * @return 文件信息封装类 FileInfo
     * @throws RuntimeException 当文件不存在、不是有效文件或发生异常时抛出
     */
    public static FileInfo getFileInfo(String uploadRootPath, String relativePath) {
        // 校验参数
        if (org.apache.commons.lang3.StringUtils.isEmpty(uploadRootPath)) {
            throw new RuntimeException("文件根路径（uploadRootPath）不能为空");
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(relativePath)) {
            throw new RuntimeException("文件相对路径（relativePath）不能为空");
        }

        // 拼接真实文件路径（跨平台兼容）
        File targetFile = Paths.get(uploadRootPath, relativePath).toFile();

        // 校验文件存在性和有效性
        validateFileExistsAndIsFile(targetFile);

        // 获取文件格式
        String fileFormat = getFileFormat(targetFile);

        // 获取文件大小
        long fileSizeBytes = targetFile.length();
        String fileSize = formatFileSize(fileSizeBytes);

        return new FileInfo(fileFormat, fileSize, fileSizeBytes);
    }

    /**
     * 根据文件根路径和相对路径删除文件
     * @param uploadRootPath 服务器文件上传根路径
     * @param relativePath 文件相对路径
     * @return true: 删除成功, false: 删除失败
     * @throws RuntimeException 当参数无效、文件不存在或不是文件时抛出
     */
    public static boolean deleteFile(String uploadRootPath, String relativePath) {
        // 校验参数
        if (org.apache.commons.lang3.StringUtils.isEmpty(uploadRootPath)) {
            throw new RuntimeException("文件根路径（uploadRootPath）不能为空");
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(relativePath)) {
            throw new RuntimeException("文件相对路径（relativePath）不能为空");
        }

        // 拼接真实文件路径
        File targetFile = Paths.get(uploadRootPath, relativePath).toFile();

        // 验证文件存在且是文件
        validateFileExistsAndIsFile(targetFile);

        try {
            // 使用Files.delete确保跨平台兼容性和更好的异常处理
            Files.delete(targetFile.toPath());
            return true;
        } catch (Exception e) {
            throw new RuntimeException("删除文件失败！路径：" + targetFile.getAbsolutePath() + "，原因：" + e.getMessage());
        }
    }

    /**
     * 批量删除文件
     * @param uploadRootPath 服务器文件上传根路径
     * @param relativePaths 多个文件的相对路径列表
     * @param continueOnError 是否在遇到错误时继续处理其他文件
     * @return 批量删除结果
     * @throws RuntimeException 当根路径无效或路径列表为空时抛出
     */
    public static BatchDeleteResult batchDeleteFiles(String uploadRootPath, List<String> relativePaths, boolean continueOnError) {
        // 校验参数
        if (org.apache.commons.lang3.StringUtils.isEmpty(uploadRootPath)) {
            throw new RuntimeException("文件根路径（uploadRootPath）不能为空");
        }
        if (relativePaths == null || relativePaths.isEmpty()) {
            throw new RuntimeException("文件相对路径列表（relativePaths）不能为空");
        }

        int totalCount = relativePaths.size();
        int successCount = 0;
        int failCount = 0;
        StringBuilder failDetails = new StringBuilder();

        for (String relativePath : relativePaths) {
            try {
                // 调用单个删除方法
                if (deleteFile(uploadRootPath, relativePath)) {
                    successCount++;
                }
            } catch (Exception e) {
                failCount++;
                failDetails.append("路径: ").append(relativePath).append("，错误: ").append(e.getMessage()).append("; ");

                // 如果不允许继续处理错误，则直接抛出异常
                if (!continueOnError) {
                    throw new RuntimeException("批量删除文件失败，在处理路径[" + relativePath + "]时发生错误: " + e.getMessage());
                }
            }
        }

        return new BatchDeleteResult(totalCount, successCount, failCount, failDetails.toString());
    }

    /**
     * 验证文件是否存在且是一个文件
     * @param file 要验证的文件
     * @throws RuntimeException 当文件不存在或不是有效文件时抛出
     */
    private static void validateFileExistsAndIsFile(File file) {
        if (!file.exists()) {
            throw new RuntimeException("文件不存在！路径：" + file.getAbsolutePath());
        }
        if (!file.isFile()) {
            throw new RuntimeException("路径指向的不是有效文件！路径：" + file.getAbsolutePath());
        }
    }

    /**
     * 获取文件格式（通过文件名后缀）
     * @param file 目标文件
     * @return 小写格式的文件后缀（如 mp4、jpg），无有效后缀则返回"未知格式"
     */
    private static String getFileFormat(File file) {
        String fileName = file.getName();
        int dotIndex = fileName.lastIndexOf(".");
        // 排除无后缀或后缀不合法的情况（如 ".gitignore" 或 "abc."）
        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
            return fileName.substring(dotIndex + 1).toLowerCase();
        }
        return "未知格式";
    }

    /**
     * 格式化文件大小（转换为 KB/MB，保留2位小数）
     * @param bytes 原始字节数
     * @return 格式化后的大小字符串（如 "2.34 MB"、"128.50 KB"）
     */
    private static String formatFileSize(long bytes) {
        if (bytes < 1024 * 1024) {
            // 小于1MB → 显示KB
            double sizeKB = (double) bytes / 1024;
            return String.format("%.2f KB", sizeKB);
        } else {
            // 大于等于1MB → 显示MB
            double sizeMB = (double) bytes / (1024 * 1024);
            return String.format("%.2f MB", sizeMB);
        }
    }
}
    